#region File Description
/*-----------------------------------------------------------------------------
 * Class: 
 *
 *  // mediator pattern? includes both ui and functionality in one class
 *
 *
 * Notes: 
 -------------------------------------------------------------------------------*/
#endregion

using System.Collections.Generic;
using System.Linq;
using Cubezicles.NeedObjects;
using Cubezicles.UI;
using Microsoft.Xna.Framework;

namespace Cubezicles
{
    /// <summary>
    /// The pane that the player can buy objects from, pulled up from coffee cup icon
    /// </summary>
    public class ItemManager : DrawableGame1Component
    {
        // List of all NeedObjects in the game world
        // .... the ones we have already bought
        public List<NeedObject> NeedObjects = new List<NeedObject>();

        // Reference objects (Maybe there's a better way to do this..........)
        // make new instances at beginning but dont add them to needobjects until bought
        internal NeedObject pinball, drink, vend, bath;

        public Node nbath, ndrink, npin, nvend;

        private static Vector3 pinballMachinePos = new Vector3(0, 0, -8),
                               vendingMachinePos = new Vector3(-4, 0, -11),
                               drinkMachinePos = new Vector3(-12, 0, -11),
                               bathroomPos = new Vector3(-28, 0, -30);

        public UI.ItemManagerPane managerPane { get; private set; }

        /// <summary>
        /// ItemManager class constructor.
        /// </summary>
        public ItemManager(Game1 game)
            : base(game)
        {
            this.DrawOrder = (int)Game1.DisplayOrder.Menus;
            
            pinball = new PinballMachine(game, pinballMachinePos);
            drink = new DrinkMachine(game, drinkMachinePos);
            vend = new VendingMachine(game, vendingMachinePos);
            bath = new Bathroom(game, bathroomPos);

            managerPane = new ItemManagerPane(game, this);
        }

        protected override void LoadContent()
        {
            Game1.Components.Add(managerPane);

            //Add nodes to the graph
            nbath = new Node(bathroomPos);
            ndrink = new Node(drinkMachinePos);
            npin = new Node(pinballMachinePos);
            nvend = new Node(vendingMachinePos);

            Game1.gra.addNode(nvend); //id = 0
            Game1.gra.addNode(nbath); //id = 1
            Game1.gra.addNode(ndrink); //id = 2
            Game1.gra.addNode(npin); //id = 3

            Game1.gra.addEdge(nvend, Game1.gra.nodes[Game1.graphi + 20]); //20 should be the top middle node.
            Game1.gra.addEdge(ndrink, nvend);
            Game1.gra.addEdge(nvend, npin);
            //Bathroom... 
            Game1.gra.addEdge(nbath, Game1.gra.nodes[Game1.graphi + 21]);

            Game1.gra.addEdge(nbath, EmployeeManager.aisleTL);
            
            base.LoadContent();
        }

        public bool HasItem(NeedObject item)
        {
            return NeedObjects.Any(i => i.name == item.name);
        }

        // Get a particular need object, null if there is none.
        public T GetItem<T>() where T : NeedObject
        {
            return NeedObjects.OfType<T>().FirstOrDefault();
        }

        // already checked if we can afford item, so buy it/get it/add it
        /// <summary>
        /// Adds the item.
        /// </summary>
        /// <param name="item">The item.</param>
        public void AddItem(NeedObject item)
        {
            switch(item.name)
            {
                case "Pinball Machine":
                    item = pinball;
                    break;
                case "Vending Machine":
                    item = vend;
                    break;
                case "Dew Machine":
                    item = drink;
                    break;
                case "Bathroom":
                    item = bath;
                    break;
                default:
                    return;
            }
            // not sure if should do this a better way....
            // use ref objects?
            NeedObjects.Add(item);
            Game1.Components.Add(item);
            Game1.MoneyManager.dailyExpenses -= item.price;
        }

        /// <summary>
        /// For initialize all method...... testing
        /// </summary>
        public void AddAllObjects()
        {
            NeedObjects.Add(pinball);
            Game1.Components.Add(pinball);

            NeedObjects.Add(drink);
            Game1.Components.Add(drink);

            NeedObjects.Add(vend);
            Game1.Components.Add(vend);

            NeedObjects.Add(bath);
            Game1.Components.Add(bath);
        }

        
        // **********
        // todo: *** reset functions
        public void Reset()
        {
           // if (NeedObjects.Count>0)
            //{
                Game1.Components.Remove(bath);
                Game1.Components.Remove(vend);
                Game1.Components.Remove(drink);
                Game1.Components.Remove(pinball);
            //}
            // the game was reset....
            // remove all items
            NeedObjects.Clear();
        }
    }
}
